/**
 * 文档解析工具
 * 
 * 用于解析不同格式的文档内容
 */

/**
 * 解析文档内容
 * @param fileContent 文件内容的ArrayBuffer
 * @param fileName 文件名称
 * @returns 解析后的文档内容和分段内容
 */
export async function parseDocument(
  fileContent: ArrayBuffer, 
  fileName: string
): Promise<{ content: string; chunks: string[] }> {
  try {
    const fileExtension = fileName.split('.').pop()?.toLowerCase();
    let content = '';
    
    // 根据文件类型选择解析方法
    switch (fileExtension) {
      case 'pdf':
        content = await parsePdfDocument(fileContent);
        break;
      case 'docx':
        content = await parseDocxDocument(fileContent);
        break;
      case 'txt':
      case 'md':
        content = await parseTextDocument(fileContent);
        break;
      default:
        throw new Error(`不支持的文件格式: ${fileExtension}`);
    }
    
    // 分割文档内容为块
    const chunks = splitTextIntoChunks(content);
    
    return { content, chunks };
  } catch (error) {
    console.error("解析文档错误:", error);
    throw new Error(`解析文档失败: ${(error as Error).message}`);
  }
}

/**
 * 解析PDF文档
 * @param fileContent 文件内容
 * @returns 提取的文本内容
 */
async function parsePdfDocument(fileContent: ArrayBuffer): Promise<string> {
  try {
    // 由于PDF解析需要第三方库如pdf.js，这里用简化的实现
    // 实际项目中应该集成PDF.js或其他PDF解析库
    
    // 模拟PDF解析，返回文本内容
    // 这里仅作为一个占位示例，实际实现应该使用PDF解析库
    const textContent = "这是从PDF提取的文本内容（示例）";
    
    return textContent;
  } catch (error) {
    console.error("解析PDF错误:", error);
    throw new Error(`解析PDF文档失败: ${(error as Error).message}`);
  }
}

/**
 * 解析DOCX文档
 * @param fileContent 文件内容
 * @returns 提取的文本内容
 */
async function parseDocxDocument(fileContent: ArrayBuffer): Promise<string> {
  try {
    // 由于DOCX解析需要第三方库如mammoth.js，这里用简化的实现
    // 实际项目中应该集成mammoth.js或其他DOCX解析库
    
    // 模拟DOCX解析，返回文本内容
    // 这里仅作为一个占位示例，实际实现应该使用DOCX解析库
    const textContent = "这是从DOCX提取的文本内容（示例）";
    
    return textContent;
  } catch (error) {
    console.error("解析DOCX错误:", error);
    throw new Error(`解析DOCX文档失败: ${(error as Error).message}`);
  }
}

/**
 * 解析文本文档(TXT, MD)
 * @param fileContent 文件内容
 * @returns 提取的文本内容
 */
async function parseTextDocument(fileContent: ArrayBuffer): Promise<string> {
  try {
    // 使用TextDecoder将ArrayBuffer转换为文本
    const textContent = new TextDecoder("utf-8").decode(fileContent);
    return textContent;
  } catch (error) {
    console.error("解析文本文档错误:", error);
    throw new Error(`解析文本文档失败: ${(error as Error).message}`);
  }
}

/**
 * 将文本分割成块
 * @param text 要分割的文本
 * @param maxChunkSize 最大块大小（字符数）
 * @returns 分割后的文本块数组
 */
function splitTextIntoChunks(text: string, maxChunkSize: number = 1000): string[] {
  if (!text || text.length === 0) {
    return [];
  }

  const chunks: string[] = [];
  let currentChunk = "";
  
  // 按段落分割
  const paragraphs = text.split(/\n\s*\n/);
  
  for (const paragraph of paragraphs) {
    // 如果当前段落过长，则进一步按句子分割
    if (paragraph.length > maxChunkSize) {
      const sentences = paragraph.split(/(?<=[.!?])\s+/);
      
      for (const sentence of sentences) {
        // 如果当前句子能添加到当前块，则添加
        if (currentChunk.length + sentence.length + 1 <= maxChunkSize) {
          currentChunk += (currentChunk ? " " : "") + sentence;
        } else {
          // 否则保存当前块并开始新块
          if (currentChunk) {
            chunks.push(currentChunk);
          }
          
          // 如果单个句子超过最大块大小，则拆分句子
          if (sentence.length > maxChunkSize) {
            const sentenceChunks = [];
            for (let i = 0; i < sentence.length; i += maxChunkSize) {
              sentenceChunks.push(sentence.substring(i, i + maxChunkSize));
            }
            chunks.push(...sentenceChunks);
            currentChunk = "";
          } else {
            currentChunk = sentence;
          }
        }
      }
    } else {
      // 如果当前段落可以添加到当前块，则添加
      if (currentChunk.length + paragraph.length + 2 <= maxChunkSize) {
        currentChunk += (currentChunk ? "\n\n" : "") + paragraph;
      } else {
        // 否则保存当前块并开始新块
        if (currentChunk) {
          chunks.push(currentChunk);
        }
        currentChunk = paragraph;
      }
    }
  }
  
  // 添加最后一个块
  if (currentChunk) {
    chunks.push(currentChunk);
  }
  
  return chunks;
} 